import React from "react";
import Moveable from "react-moveable";
import ReactForEcharts from '../../../../components/ReactForEcharts';
import Wrapper from "../../../../layout/Wrapper";
import { DATASOURCE_KEY } from "../../../../store/constants"; 
import "./index.scss";
interface IRenderForConfigProps {
  config: Array<any>;
  pageConfig?: any;
  editing?: boolean;
  onSelect?: (id: string, data: any) => void;
  onChange?: (type: string, value: any, activeId?: string) => void;
  activeId?: string;
  blueprint?: any;
  [key: string]: any;
}
interface IRenderForConfigState {
  cachePosition: [number, number];
  cacheSize: [number, number];
}
/* 根据size生成样式对象 */
function getSizeStyle(size: [number, number], ) {
  return { width: size[0], height: size[1] };
}
/* 根据position生成位置信息 */
function getPositionStyle(position: [number, number]) {
  return { top: position[0], left: position[1] };
}
export default class RenderForConfig extends React.Component<IRenderForConfigProps, IRenderForConfigState> {
  frame = {
    translate: [0, 0],
  };
  constructor(props: IRenderForConfigProps) {
    super(props);
    this.state = this.initState();
  }
  initState: any = () => {
    const { config, activeId } = this.props;
    if (!activeId) return { cachePosition: [0, 0], cacheSize: [0, 0] };
    const comp = config.find(component => component.id === activeId);
    if (comp) return { cachePosition: [comp.style?.top || 0, comp.style?.left || 0], cacheSize: [comp.style?.width || 0, comp.style?.height || 0] };
    return { cachePosition: [0, 0], cacheSize: [0, 0] };
  }
  selectElementHandler = (conf: any) => {
    const { onSelect } = this.props;
    const { width = 200, height = 200, top = 0, left = 0 } = conf.style;
    this.setState({ cachePosition: [top, left], cacheSize: [width, height] });
    onSelect && onSelect(conf.id, conf);
  }
  renderBaseComponent = (nodeName: string, config: any) => {
    const Node = require("visbar-component")[nodeName];
    if (!Node) return <p>当前物料控件不存在，请联系管理员添加...</p>
    return <Node {...config.props} style={config.style} />
  }
  render() {
    const { config, activeId, pageConfig, onChange } = this.props;
    const { cacheSize, cachePosition } = this.state;
    return <div className="page-editor-main" style={pageConfig.style}>
      {config.map(conf => <Wrapper key={conf.id}
        style={
          activeId === conf.id
            ? { ...conf.style, ...getSizeStyle(cacheSize), ...getPositionStyle(cachePosition) }
            : conf.style
        }
        id={conf.id} onClick={() => this.selectElementHandler(conf)} editing={true}>
        {
          conf.node
            ? this.renderBaseComponent(conf.node, conf)
            : (<ReactForEcharts
                options={conf.props} dataSourceConfig={conf.dataSource?.[DATASOURCE_KEY] || []}
                geoMap={conf.dataSource?.geoMap || []}
              />)
        }
      </Wrapper>)}
      <Moveable 
        target={(document.querySelector(`.edit-comp-${activeId}`) as any)}
        draggable={true}
        pinchable={true}
        resizable={true}
        throttleResize={10}
        throttleDrag={10}
        onDrag={(e) => this.setState({ cachePosition: [e.top, e.left] })}
        onDragEnd={() => onChange && onChange("style", getPositionStyle(cachePosition), activeId)}
        onResizeStart={({ target, set, setOrigin, dragStart }) => {
            setOrigin(["%", "%"]);
            const style = window.getComputedStyle(target);
            const cssWidth = parseFloat(style.width);
            const cssHeight = parseFloat(style.height);
            set([cssWidth, cssHeight]);
            dragStart && dragStart.set(this.frame.translate);
        }}
        onResize={(e) => {
          const { target, drag } = e;
          this.setState({ cacheSize: [e.width, e.height] })
          this.frame.translate = drag.beforeTranslate;
          target.style.transform = `translate(${drag.beforeTranslate[0]}px, ${drag.beforeTranslate[1]}px)`;
        }}
        onResizeEnd={() => onChange && onChange("style", getSizeStyle(cacheSize), activeId)}
      />
    </div>
  }
}